#include <bits/stdc++.h>
#define int long long 
using namespace std;

const int M=15;
int dp[40][1<<M]; // 表示 第 i 行 状态为 j 时能带走的最多宠物数
// 这个 j 的二进制为表示 每一个位置的情况

int n,m;
int val[40]; // 表示每一行的状态
int valid[1<<M];


// 获取 1 的个数
int get_cnt(int val){
	int ans=0;
	while(val!=0){
		ans++;
		val = (val&(val-1));
	}
	return ans;
}

void solve(){
	cin>>n>>m;
	for (int i=1;i<=n;i++) {
		for (int j=1;j<=m;j++) {
			int a;
			cin >> a;
			val[i] |= (a<<(j-1)); // 表示第 j 列是否已经被占用了
		}
	}
	
	
	// 处理每种状态是否合法, 是否有相邻的 1
	for(int i=0;i<(1<<m);i++){
		if ((i&(i<<1)) != 0) {
			valid[i] = false;
		} else {
			valid[i] = true;
		}
	}
	
	// 
	for(int i=1;i<=n;i++){
		// 枚举所有的状态
		for(int j=0;j<(1<<m);j++){ // 当前这一行的状态, 并且列举的直接就是 放宠物的情况, 不在食物位置放置的情况
			if (valid[j] && (j&val[i])==0) { // 有效并且没有占用 食物的位置
				for(int k=0;k<(1<<m);k++){ // 列举前一行的状态
					
					
					/// 这里面注意 k 合法是 k 与 val[i-1] & 的值是 0
					if (valid[k] && (k&val[i-1])==0 && (j&k)==0) { // 同样前一行也必须是合法的状态且两行没有相邻的
						dp[i][j] = max(dp[i][j], dp[i-1][k]+get_cnt(j));
//						cout<<"i "<<i<<"j "<<j<<"k "<<k<<' '<<dp[i][j]<<'\n';
					}
				}
			}
			

//			cout<<i<<' '<<j<<' '<<dp[i][j]<<'\n';
		}
		
	}
	
	int ans=0;
	// 最后遍历最后一行的所有的状态
	for (int i=0;i<(1<<m);i++) {
		ans=max(ans, dp[n][i]);
	}
	
	cout << ans <<'\n'; // 最后将食物减去
}


signed main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	solve();
	return 0;
}
